/*******************************************************************************
 * Copyright (c) Jonathan Buck - jonbuck16@gmail.com
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    jonbuck16@gmail.com - initial API and implementation
 *******************************************************************************/
package net.jonbuck.tassoo.ui.dialog;

import java.util.ArrayList;
import java.util.List;

import net.jonbuck.tassoo.model.AttachmentType;
import net.jonbuck.tassoo.ui.util.ApplicationImages;
import net.jonbuck.tassoo.ui.util.CommonImages;
import net.jonbuck.tassoo.ui.util.GalleryWidgetValueProperty;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.ValidationStatusProvider;
import org.eclipse.core.databinding.beans.BeanProperties;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jface.databinding.dialog.TitleAreaDialogSupport;
import org.eclipse.jface.databinding.dialog.ValidationMessageProvider;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.nebula.widgets.gallery.DefaultGalleryItemRenderer;
import org.eclipse.nebula.widgets.gallery.Gallery;
import org.eclipse.nebula.widgets.gallery.GalleryItem;
import org.eclipse.nebula.widgets.gallery.NoGroupRenderer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

/**
 * 
 * 
 * @since 1.0.0
 */
public class AttachmentTypeDialog extends TitleAreaDialog {

	/** ... TODO Javadoc ... */
	private AttachmentType attachmentType;

	/** ... TODO Javadoc ... */
	private String title;

	/** ... TODO Javadoc ... */
	private String message;

	/** ... TODO Javadoc ... */
	private DataBindingContext bindingContext;

	/** ... TODO Javadoc ... */
	private Text nameText;

	/** ... TODO Javadoc ... */
	private Text commandText;

	/** ... TODO Javadoc ... */
	private Text extensionText;

	/** ... TODO Javadoc ... */
	private Combo typeCombo;

	/** ... TODO Javadoc ... */
	private EList<AttachmentType> allTypes;

	/** ... TODO Javadoc ... */
	private Gallery gallery;
	
	/** ... TODO Javadoc ... */
	private Text selectionExpressionText;
	
	/** ... TODO Javadoc ... */
	private Text argumentsText;

	/**
	 * ... TODO Javadoc ...
	 * 
	 * @param parentShell
	 * @param createAttachmentType
	 * @param attachmenttypedialog_addtype_title
	 * @param attachmenttypedialog_addtype_message
	 */
	public AttachmentTypeDialog(Shell parentShell, AttachmentType attachmentType, EList<AttachmentType> allTypes, String title,
			String message) {
		super(parentShell);
		setAttachmentType(attachmentType);
		this.title = title;
		this.message = message;
		this.allTypes = allTypes;
	}

	/**
	 * ... TODO Javadoc ...
	 */
	public void create() {
		super.create();
		setTitle(title);
		setMessage(message);
		setTitleImage(CommonImages.getImage(CommonImages.WIZBAN_ATTACHMENT));
	}

	/**
	 * ... TODO Javadoc ...
	 */
	protected Control createDialogArea(Composite parent) {
		final Composite outerContainer = (Composite) super.createDialogArea(parent);

		Composite container = new Composite(outerContainer, SWT.NONE);
		GridLayout containerLayout = new GridLayout(2, false);
		containerLayout.marginTop = containerLayout.marginBottom = containerLayout.marginLeft = containerLayout.marginRight = 15;
		containerLayout.verticalSpacing = 15;
		container.setLayout(containerLayout);
		container.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

		initializeDialogUnits(container);

		Label lblType = new Label(container, SWT.NONE);
		lblType.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblType.setText("Type:");

		typeCombo = new Combo(container, SWT.NONE);
		typeCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		typeCombo.setItems(createTypeList());

		Label lblName = new Label(container, SWT.NONE);
		lblName.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblName.setText("Name:");

		nameText = new Text(container, SWT.BORDER);
		GridData gd_nameText = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_nameText.heightHint = 15;
		nameText.setLayoutData(gd_nameText);

		Label lblCommand = new Label(container, SWT.NONE);
		lblCommand.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblCommand.setText("Command:");

		commandText = new Text(container, SWT.BORDER);
		GridData gd_commandText = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_commandText.heightHint = 15;
		commandText.setLayoutData(gd_commandText);

		Label lblArguments = new Label(container, SWT.NONE);
		lblArguments.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblArguments.setText("Arguments:");

		argumentsText = new Text(container, SWT.BORDER);
		argumentsText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		Label lblExtensions = new Label(container, SWT.NONE);
		lblExtensions.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblExtensions.setText("Extension(s):");

		extensionText = new Text(container, SWT.BORDER);
		GridData gd_extensionText = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
		gd_extensionText.heightHint = 15;
		extensionText.setLayoutData(gd_extensionText);

		Label lblSelectionExpression = new Label(container, SWT.NONE);
		lblSelectionExpression.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		lblSelectionExpression.setText("Selection Expression:");

		selectionExpressionText = new Text(container, SWT.BORDER);
		selectionExpressionText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		Label lblIcon = new Label(container, SWT.NONE);
		lblIcon.setLayoutData(new GridData(SWT.RIGHT, SWT.TOP, false, false, 1, 1));
		lblIcon.setText("Icon:");

		gallery = new Gallery(container, SWT.BORDER | SWT.V_SCROLL);
		GridData gd_gallery = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
		gd_gallery.heightHint = 100;
		gallery.setLayoutData(gd_gallery);

		NoGroupRenderer groupRenderer = new NoGroupRenderer();
		groupRenderer.setItemWidth(40);
		groupRenderer.setItemHeight(40);
		groupRenderer.setAutoMargin(true);

		gallery.setGroupRenderer(groupRenderer);
		gallery.setItemRenderer(new DefaultGalleryItemRenderer());

		createAppllicationIcons(gallery);

		// Build the separator line
		Label titleBarSeparator = new Label(parent, SWT.HORIZONTAL | SWT.SEPARATOR);
		titleBarSeparator.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));

		initDataBindings();
		initBindingSupport();

		return container;
	}

	/**
	 * <p>
	 * <b>Generates a list of currently defined attachment types for the user to
	 * select from.</b>
	 * </p>
	 * 
	 * @return
	 */
	private String[] createTypeList() {
		int count = 0;
		List<String> existingTypes = new ArrayList<String>();
		for (AttachmentType type : allTypes) {
			if (!existingTypes.contains(type.getType())) {
				existingTypes.add(type.getType());
			}
		}
		String[] attachmentTypes = new String[existingTypes.size()];
		for (String type : existingTypes) {
			attachmentTypes[count++] = type;
		}
		return attachmentTypes;
	}

	/**
	 * <p>
	 * <b>Creates a list of gallery items displaying the application icons.</b>
	 * </p>
	 * 
	 * @param gallery
	 *            the gallery to add the items to.
	 */
	private void createAppllicationIcons(Gallery gallery) {
		GalleryItem applications = new GalleryItem(gallery, SWT.NONE);

		GalleryItem page_attach = new GalleryItem(applications, SWT.NONE);
		page_attach.setImage(ApplicationImages.getImage("icons/apps/page_attach.gif"));
		page_attach.setData("filePath", "icons/apps/page_attach.gif");

		GalleryItem page_code = new GalleryItem(applications, SWT.NONE);
		page_code.setImage(ApplicationImages.getImage("icons/apps/page_code.gif"));
		page_code.setData("filePath", "icons/apps/page_code.gif");

		GalleryItem page_edit = new GalleryItem(applications, SWT.NONE);
		page_edit.setImage(ApplicationImages.getImage("icons/apps/page_edit.gif"));
		page_edit.setData("filePath", "icons/apps/page_edit.gif");

		GalleryItem page_excel = new GalleryItem(applications, SWT.NONE);
		page_excel.setImage(ApplicationImages.getImage("icons/apps/page_excel.gif"));
		page_excel.setData("filePath", "icons/apps/page_excel.gif");

		GalleryItem page_gear = new GalleryItem(applications, SWT.NONE);
		page_gear.setImage(ApplicationImages.getImage("icons/apps/page_gear.gif"));
		page_gear.setData("filePath", "icons/apps/page_gear.gif");

		GalleryItem page_green = new GalleryItem(applications, SWT.NONE);
		page_green.setImage(ApplicationImages.getImage("icons/apps/page_green.gif"));
		page_green.setData("filePath", "icons/apps/page_green.gif");

		GalleryItem page_paintbrush = new GalleryItem(applications, SWT.NONE);
		page_paintbrush.setImage(ApplicationImages.getImage("icons/apps/page_paintbrush.gif"));
		page_paintbrush.setData("filePath", "icons/apps/page_paintbrush.gif");

		GalleryItem page_red = new GalleryItem(applications, SWT.NONE);
		page_red.setImage(ApplicationImages.getImage("/icons/apps/page_red.gif"));
		page_red.setData("filePath", "/icons/apps/page_red.gif");

		GalleryItem page_save = new GalleryItem(applications, SWT.NONE);
		page_save.setImage(ApplicationImages.getImage("/icons/apps/page_save.gif"));
		page_save.setData("filePath", "/icons/apps/page_save.gif");

		GalleryItem page_white_acrobat = new GalleryItem(applications, SWT.NONE);
		page_white_acrobat.setImage(ApplicationImages.getImage("/icons/apps/page_white_acrobat.gif"));
		page_white_acrobat.setData("filePath", "/icons/apps/page_white_acrobat.gif");

		GalleryItem page_white_c = new GalleryItem(applications, SWT.NONE);
		page_white_c.setImage(ApplicationImages.getImage("/icons/apps/page_white_c.gif"));
		page_white_c.setData("filePath", "/icons/apps/page_white_c.gif");

		GalleryItem page_white_cd = new GalleryItem(applications, SWT.NONE);
		page_white_cd.setImage(ApplicationImages.getImage("/icons/apps/page_white_cd.gif"));
		page_white_cd.setData("filePath", "/icons/apps/page_white_cd.gif");

		GalleryItem page_white_code_red = new GalleryItem(applications, SWT.NONE);
		page_white_code_red.setImage(ApplicationImages.getImage("/icons/apps/page_white_code_red.gif"));
		page_white_code_red.setData("filePath", "/icons/apps/page_white_code_red.gif");

		GalleryItem page_white_compress = new GalleryItem(applications, SWT.NONE);
		page_white_compress.setImage(ApplicationImages.getImage("/icons/apps/page_white_compress.gif"));
		page_white_compress.setData("filePath", "/icons/apps/page_white_compress.gif");

		GalleryItem page_white_cup = new GalleryItem(applications, SWT.NONE);
		page_white_cup.setImage(ApplicationImages.getImage("/icons/apps/page_white_cup.gif"));
		page_white_cup.setData("filePath", "/icons/apps/page_white_cup.gif");

		GalleryItem page_white_dvd = new GalleryItem(applications, SWT.NONE);
		page_white_dvd.setImage(ApplicationImages.getImage("/icons/apps/page_white_dvd.gif"));
		page_white_dvd.setData("filePath", "/icons/apps/page_white_dvd.gif");

		GalleryItem page_white_excel = new GalleryItem(applications, SWT.NONE);
		page_white_excel.setImage(ApplicationImages.getImage("/icons/apps/page_white_excel.gif"));
		page_white_excel.setData("filePath", "/icons/apps/page_white_excel.gif");

		GalleryItem page_white_find = new GalleryItem(applications, SWT.NONE);
		page_white_find.setImage(ApplicationImages.getImage("/icons/apps/page_white_find.gif"));
		page_white_find.setData("filePath", "/icons/apps/page_white_find.gif");

		GalleryItem page_white_flash = new GalleryItem(applications, SWT.NONE);
		page_white_flash.setImage(ApplicationImages.getImage("/icons/apps/page_white_flash.gif"));
		page_white_flash.setData("filePath", "/icons/apps/page_white_flash.gif");

		GalleryItem page_thunderbird = new GalleryItem(applications, SWT.NONE);
		page_thunderbird.setImage(ApplicationImages.getImage("/icons/apps/page_thunderbird.gif"));
		page_thunderbird.setData("filePath", "/icons/apps/page_thunderbird.gif");

		GalleryItem page_white_gear = new GalleryItem(applications, SWT.NONE);
		page_white_gear.setImage(ApplicationImages.getImage("/icons/apps/page_white_gear.gif"));
		page_white_gear.setData("filePath", "/icons/apps/page_white_gear.gif");

		GalleryItem page_white_get = new GalleryItem(applications, SWT.NONE);
		page_white_get.setImage(ApplicationImages.getImage("/icons/apps/page_white_get.gif"));
		page_white_get.setData("filePath", "/icons/apps/page_white_get.gif");

		GalleryItem page_firefox = new GalleryItem(applications, SWT.NONE);
		page_firefox.setImage(ApplicationImages.getImage("/icons/apps/page_firefox.gif"));
		page_firefox.setData("filePath", "/icons/apps/page_firefox.gif");

		GalleryItem page_white_h = new GalleryItem(applications, SWT.NONE);
		page_white_h.setImage(ApplicationImages.getImage("/icons/apps/page_white_h.gif"));
		page_white_h.setData("filePath", "/icons/apps/page_white_h.gif");

		GalleryItem page_white_key = new GalleryItem(applications, SWT.NONE);
		page_white_key.setImage(ApplicationImages.getImage("/icons/apps/page_white_key.gif"));
		page_white_key.setData("filePath", "/icons/apps/page_white_key.gif");

		GalleryItem page_white_link = new GalleryItem(applications, SWT.NONE);
		page_white_link.setImage(ApplicationImages.getImage("/icons/apps/page_white_link.gif"));
		page_white_link.setData("filePath", "/icons/apps/page_white_link.gif");

		GalleryItem page_white_paint = new GalleryItem(applications, SWT.NONE);
		page_white_paint.setImage(ApplicationImages.getImage("/icons/apps/page_white_paint.gif"));
		page_white_paint.setData("filePath", "/icons/apps/page_white_paint.gif");

		GalleryItem page_white_php = new GalleryItem(applications, SWT.NONE);
		page_white_php.setImage(ApplicationImages.getImage("/icons/apps/page_white_php.gif"));
		page_white_php.setData("filePath", "/icons/apps/page_white_php.gif");

		GalleryItem page_white_picture = new GalleryItem(applications, SWT.NONE);
		page_white_picture.setImage(ApplicationImages.getImage("/icons/apps/page_white_picture.gif"));
		page_white_picture.setData("filePath", "/icons/apps/page_white_picture.gif");

		GalleryItem page_white_powerpoint = new GalleryItem(applications, SWT.NONE);
		page_white_powerpoint.setImage(ApplicationImages.getImage("/icons/apps/page_white_powerpoint.gif"));
		page_white_powerpoint.setData("filePath", "/icons/apps/page_white_powerpoint.gif");

		GalleryItem page_white_ruby = new GalleryItem(applications, SWT.NONE);
		page_white_ruby.setImage(ApplicationImages.getImage("/icons/apps/page_white_ruby.gif"));
		page_white_ruby.setData("filePath", "/icons/apps/page_white_ruby.gif");

		GalleryItem page_white_star = new GalleryItem(applications, SWT.NONE);
		page_white_star.setImage(ApplicationImages.getImage("/icons/apps/page_white_star.gif"));
		page_white_star.setData("filePath", "/icons/apps/page_white_star.gif");

		GalleryItem page_white_vector = new GalleryItem(applications, SWT.NONE);
		page_white_vector.setImage(ApplicationImages.getImage("/icons/apps/page_white_vector.gif"));
		page_white_vector.setData("filePath", "/icons/apps/page_white_vector.gif");

		GalleryItem page_white_visualstudio = new GalleryItem(applications, SWT.NONE);
		page_white_visualstudio.setImage(ApplicationImages.getImage("/icons/apps/page_white_visualstudio.gif"));
		page_white_visualstudio.setData("filePath", "/icons/apps/page_white_visualstudio.gif");

		GalleryItem page_white_word = new GalleryItem(applications, SWT.NONE);
		page_white_word.setImage(ApplicationImages.getImage("/icons/apps/page_white_word.gif"));
		page_white_word.setData("filePath", "/icons/apps/page_white_word.gif");

		GalleryItem page_white_zip = new GalleryItem(applications, SWT.NONE);
		page_white_zip.setImage(ApplicationImages.getImage("/icons/apps/page_white_zip.gif"));
		page_white_zip.setData("filePath", "/icons/apps/page_white_zip.gif");

		GalleryItem page_white = new GalleryItem(applications, SWT.NONE);
		page_white.setImage(ApplicationImages.getImage("/icons/apps/page_white.gif"));
		page_white.setData("filePath", "/icons/apps/page_white.gif");

		GalleryItem page_word = new GalleryItem(applications, SWT.NONE);
		page_word.setImage(ApplicationImages.getImage("/icons/apps/page_word.gif"));
		page_word.setData("filePath", "/icons/apps/page_word.gif");

		GalleryItem page_world = new GalleryItem(applications, SWT.NONE);
		page_world.setImage(ApplicationImages.getImage("/icons/apps/page_world.gif"));
		page_world.setData("filePath", "/icons/apps/page_world.gif");

		GalleryItem page_oowriter = new GalleryItem(applications, SWT.NONE);
		page_oowriter.setImage(ApplicationImages.getImage("/icons/apps/page_oowriter.gif"));
		page_oowriter.setData("filePath", "/icons/apps/page_oowriter.gif");

		GalleryItem page_oodraw = new GalleryItem(applications, SWT.NONE);
		page_oodraw.setImage(ApplicationImages.getImage("/icons/apps/page_oodraw.gif"));
		page_oodraw.setData("filePath", "/icons/apps/page_oodraw.gif");

		GalleryItem page_ooimpress = new GalleryItem(applications, SWT.NONE);
		page_ooimpress.setImage(ApplicationImages.getImage("/icons/apps/page_ooimpress.gif"));
		page_ooimpress.setData("filePath", "/icons/apps/page_ooimpress.gif");

		GalleryItem page_oocalc = new GalleryItem(applications, SWT.NONE);
		page_oocalc.setImage(ApplicationImages.getImage("/icons/apps/page_oocalc.gif"));
		page_oocalc.setData("filePath", "/icons/apps/page_oocalc.gif");
	}

	/**
	 * <p>
	 * <b>Initialises the binding support for the dialog.</b><br/>
	 * This method initialises a <code>TitleAreaDialogSupport</code> class which
	 * links an errors that are created from the data binding code to error
	 * messages that are displayed in the title area of the dialog. In order to
	 * manage the enablement of the OK button we need to subclass the validation
	 * message provider so that we can add code that either enables or disables
	 * the button based on whether there are any errors.
	 * </p>
	 */
	private void initBindingSupport() {
		TitleAreaDialogSupport tads = TitleAreaDialogSupport.create(this, bindingContext);
		tads.setValidationMessageProvider(new ValidationMessageProvider() {
			public String getMessage(ValidationStatusProvider statusProvider) {
				if (statusProvider == null) {
					return message;
				}
				return super.getMessage(statusProvider);
			}

			public int getMessageType(ValidationStatusProvider statusProvider) {
				int type = super.getMessageType(statusProvider);
				if (getButton(IDialogConstants.OK_ID) != null) {
					getButton(IDialogConstants.OK_ID).setEnabled(type != IMessageProvider.ERROR);
				}
				return type;
			}
		});
	}

	/**
	 * ... TODO Javadoc ...
	 */
	private void initDataBindings() {
		bindingContext = new DataBindingContext();

		IObservableValue typeObserveWidget = WidgetProperties.selection().observe(typeCombo);
		IObservableValue typeObserveValue = BeanProperties.value(AttachmentType.class, "type").observe(attachmentType);
		bindingContext.bindValue(typeObserveWidget, typeObserveValue, null, null);

		IObservableValue nameObserveWidget = WidgetProperties.text(SWT.Modify).observe(nameText);
		IObservableValue nameObserveValue = BeanProperties.value(AttachmentType.class, "name").observe(attachmentType);
		bindingContext.bindValue(nameObserveWidget, nameObserveValue, null, null);

		IObservableValue commandObserveWidget = WidgetProperties.text(SWT.Modify).observe(commandText);
		IObservableValue commandObserveValue = BeanProperties.value(AttachmentType.class, "command").observe(attachmentType);
		bindingContext.bindValue(commandObserveWidget, commandObserveValue, null, null);

		IObservableValue argumentObserveWidget = WidgetProperties.text(SWT.Modify).observe(argumentsText);
		IObservableValue argumentObserveValue = BeanProperties.value(AttachmentType.class, "arguments").observe(attachmentType);
		bindingContext.bindValue(argumentObserveWidget, argumentObserveValue, null, null);

		IObservableValue extensionObserveWidget = WidgetProperties.text(SWT.Modify).observe(extensionText);
		IObservableValue extensionObserveValue = BeanProperties.value(AttachmentType.class, "extension").observe(attachmentType);
		bindingContext.bindValue(extensionObserveWidget, extensionObserveValue, null, null);

		IObservableValue selectionExpressionObserveWidget = WidgetProperties.text(SWT.Modify).observe(selectionExpressionText);
		IObservableValue selectionExpressionObserveValue = BeanProperties.value(AttachmentType.class, "selectionExpression")
				.observe(attachmentType);
		bindingContext.bindValue(selectionExpressionObserveWidget, selectionExpressionObserveValue, null, null);

		IObservableValue galleryObserveWidget = new GalleryWidgetValueProperty().observe(gallery);
		IObservableValue galleryObserveValue = BeanProperties.value(AttachmentType.class, "icon").observe(attachmentType);
		bindingContext.bindValue(galleryObserveWidget, galleryObserveValue, null, null);

	}

	/**
	 * @return the attachmentType
	 */
	public AttachmentType getAttachmentType() {
		return attachmentType;
	}

	/**
	 * @param attachmentType
	 *            the attachmentType to set
	 */
	public void setAttachmentType(AttachmentType attachmentType) {
		this.attachmentType = attachmentType;
	}

}
